package com.binfast.codegen.gen;

import cn.hutool.core.util.StrUtil;
import org.beetl.sql.core.*;
import org.beetl.sql.core.db.MySqlStyle;
import org.beetl.sql.core.db.TableDesc;
import org.beetl.sql.core.kit.StringKit;
import org.beetl.sql.ext.DebugInterceptor;
import org.beetl.sql.ext.gen.GenConfig;
import org.beetl.sql.ext.gen.MDCodeGen;

import java.io.File;
import java.io.FileWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;

public class genPoJo {


//    public static void main (String[] args) {

        //生成全部代码
//        genCodeAll(sqlManager);

        //根据表生成PoJo实体及SQL.md
//        genCode("user_0","会员",getSQLManager());

//    }
    String basePackageName;
    String projectSrcPath;
    String projectResourcePath;
    String servicePath;
    String serviceResourcePath;
    String serviceName;
    String dtoParamPath;
    String dtoParamResourcePath;
    String dtoParamName;
    String adminPath;
    String daoSrcPath;
    String daoResourcePath;
    String daoPath;

    public genPoJo() {
    }

    public genPoJo(String basePackageName, String projectSrcPath, String projectResourcePath,
                   String servicePath, String serviceResourcePath, String serviceName,
                   String dtoParamPath, String dtoParamResourcePath, String dtoParamName,
                   String adminPath, String daoSrcPath, String daoResourcePath, String daoPath) {
        this.basePackageName = basePackageName;
        this.projectSrcPath = projectSrcPath;
        this.projectResourcePath = projectResourcePath;
        this.servicePath = servicePath;
        this.serviceResourcePath = serviceResourcePath;
        this.serviceName = serviceName;
        this.dtoParamPath = dtoParamPath;
        this.dtoParamResourcePath = dtoParamResourcePath;
        this.dtoParamName = dtoParamName;
        this.adminPath = adminPath;
        this.daoSrcPath = daoSrcPath;
        this.daoResourcePath = daoResourcePath;
        this.daoPath = daoPath;
    }

    private SQLManager sqlManager;

    public void setSqlManager(SQLManager sqlManager) {
        SQLLoader loader = new ClasspathLoader("/sql");
        sqlManager.setSqlLoader(loader);
        this.sqlManager = sqlManager;
    }

    private static SQLManager getSQLManager() {
        MySqlStyle style = new MySqlStyle();
        ConnectionSource source = ConnectionSourceHelper.getSimple(MysqlDBConfig.driver, MysqlDBConfig.url, MysqlDBConfig.userName, MysqlDBConfig.password);
        SQLLoader loader = new ClasspathLoader("/sql");
        return new SQLManager(style, loader, source, new UnderlinedNameConversion(), new Interceptor[]{new DebugInterceptor()});
    }

    public  void genCode(String preTableName, String tableName, String classTitle, SQLManager sqlManager) {
        setSqlManager(sqlManager);
        //生成model\sql\dao
        genCodePoJo(preTableName,tableName);
        //生成md
        genMdAndDao(preTableName,tableName);
        //生成controllers
        genCodeContrl(preTableName,tableName, classTitle);
        //生成services
        genCodeServ(preTableName,tableName, classTitle);
        //生成dto\params
        genCodeDtoParam(preTableName,tableName, classTitle);
    }

    public  void genCodeContrl(String preTableName, String tableName,String classTitle) {
        try {
            CommonCodeGen.setSrcPathRelativeToSrc(projectSrcPath);
            CommonCodeGen.setResourcePathRelativeToSrc(projectResourcePath);
            //生成controller
            CommonCodeGen controllerGen = new CommonCodeGen(basePackageName+adminPath+".controller","/gen/controller.btl","Ctrl",basePackageName+serviceName+".services",basePackageName+dtoParamName);
            controllerGen.genCode(sqlManager,preTableName,tableName);

        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void genCodeServ(String preTableName, String tableName,String classTitle) {
        try {
            CommonCodeGen.setSrcPathRelativeToSrc(servicePath);
            CommonCodeGen.setResourcePathRelativeToSrc(serviceResourcePath);
            //生成service
            CommonCodeGen serviceCodeGen = new CommonCodeGen(basePackageName+serviceName+".services","/gen/service.btl","Serv",basePackageName+serviceName,basePackageName+dtoParamName);
            serviceCodeGen.genCode(sqlManager,preTableName,tableName);
            CommonCodeGen serviceImplCodeGen = new CommonCodeGen(basePackageName+serviceName+".services.impl","/gen/service.impl.btl","ServImpl",classTitle,basePackageName+serviceName,basePackageName+dtoParamName);
            serviceImplCodeGen.genCode(sqlManager,preTableName,tableName);

        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void genCodeDtoParam(String preTableName, String tableName,String classTitle) {
        try {
            CommonCodeGen.setSrcPathRelativeToSrc(dtoParamPath);
            CommonCodeGen.setResourcePathRelativeToSrc(dtoParamResourcePath);
            //生成dto\param
            CommonCodeGen listDTOCodeGen = new CommonCodeGen(basePackageName+dtoParamName+".dto","/gen/dto.list.btl","ListDTO");
            listDTOCodeGen.genCode(sqlManager,preTableName,tableName,true);
            CommonCodeGen detailDTOCodeGen = new CommonCodeGen(basePackageName+dtoParamName+".dto","/gen/dto.detail.btl","DTO");
            detailDTOCodeGen.genCode(sqlManager,preTableName,tableName,true);
            CommonCodeGen listParamCodeGen = new CommonCodeGen(basePackageName+dtoParamName+".params","/gen/param.list.btl","ListParam");
            listParamCodeGen.genCode(sqlManager,preTableName,tableName,true);
            CommonCodeGen detailParamCodeGen = new CommonCodeGen(basePackageName+dtoParamName+".params","/gen/param.detail.btl","Param");
            detailParamCodeGen.genCode(sqlManager,preTableName,tableName,true);

        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    public  void genMdAndDao(String preTableName,String tableName) {
        TableDesc desc = sqlManager.getMetaDataManager().getTable(preTableName+tableName);
        try {
            CommonCodeGen.setSrcPathRelativeToSrc(daoSrcPath);
            CommonCodeGen.setResourcePathRelativeToSrc(daoResourcePath);
            MDCodeGen mdCodeGen = new MDCodeGen();
            mdCodeGen.setMapperTemplate(new GenConfig().getTemplate("/gen/sql.md.btl"));
            String target = CommonCodeGen.getJavaResourcePath()+ "/sql/" + StrUtil.toCamelCase(tableName) + ".md";
            FileWriter writer = new FileWriter(new File(target));
            mdCodeGen.genCode(sqlManager.getBeetl(),desc,sqlManager.getNc(),"m",writer);

            //生成Dao
            CommonCodeGen daoGen = new CommonCodeGen(basePackageName+daoPath+".dao","/gen/dao.btl","Dao");
            daoGen.genCode(sqlManager,preTableName,tableName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public  void genCodePoJo(String preTableName, String tableName) {
        try {
            CommonCodeGen.setSrcPathRelativeToSrc(dtoParamPath);
            CommonCodeGen.setResourcePathRelativeToSrc(dtoParamResourcePath);
            //生成实体
            GenConfig config = new GenConfig("/gen/entity.btl");
            config.preferBigDecimal(true);
            config.setBaseClass("BaseModel");
            if(StrUtil.isNotBlank(preTableName))config.setIgnorePrefix(StringKit.toUpperCaseFirstOne(StringKit.deCodeUnderlined(preTableName.toLowerCase())));
//            DaoCodeGen daoGen = new DaoCodeGen(basePackageName+daoPath+".dao");
//            daoGen.setMapperTemplate((new GenConfig("/gen/dao.btl")).getTemplate());
//            config.codeGens.add(daoGen);

            if(StrUtil.isBlank(tableName)) {
                sqlManager.genALL(basePackageName+dtoParamName+".model", config, null);
            }else {
                sqlManager.genPojoCode(preTableName+tableName, basePackageName+dtoParamName+".model",CommonCodeGen.getJavaSRCPath(),config);
//                sqlManager.genSQLFile(tableName, config);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    static class MySqlConnectionSource implements ConnectionSource {
        @Override
        public Connection getMetaData() {
            return null;
        }

        public MySqlConnectionSource() {

        }

        private Connection _getConn(){
            String driver = MysqlDBConfig.driver;
            String dbName = MysqlDBConfig.dbName;
            String password = MysqlDBConfig.password;
            String userName = MysqlDBConfig.userName;
            String url = MysqlDBConfig.url;
            Connection conn = null;
            try {
                Class.forName(driver);
                conn = DriverManager.getConnection(url, userName,
                        password);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return conn;
        }

        public Connection getMaster() {
            return _getConn();
        }

        public Connection getConn(String sqlId, boolean isUpdate, String sql, List paras) {
            return _getConn();
        }



        public boolean isTransaction() {
            // TODO Auto-generated method stub
            return false;
        }

        public Connection getSlave() {
            return this.getMaster();
        }

        public void forceBegin(boolean isMaster) {
            // TODO Auto-generated method stub

        }

        public void forceEnd() {
            // TODO Auto-generated method stub

        }

//        @Override
//        public Connection getMetaData() {
//            // TODO Auto-generated method stub
//            return null;
//        }




    }

    static class MysqlDBConfig {
        public static String driver = "com.mysql.jdbc.Driver";
        public static String dbName = "binfast";
        public static String password = "root";
        public static String userName = "root";
        public static String url = "jdbc:mysql://127.0.0.1:3306/" + dbName+"?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8";

    }
}
